3 格式化输入/输出

3.1 printf函数

语法:printf(格式串,表达式1,表达式2,...)
转换说明(conversion specification):以字符%开头,用来表示打印过程中填充了值的占位符。%后面的信息指定了把数值从内部(二进制)形式转换成打印(字符)形式的方法。
注意:

  1. 单独调用一次prinf函数时可以打印的值的个数没有限制
  2. c语言编译器不会检测格式串中转换说明的数据是否和输出项的数量相匹配
  3. 也不检测转换说明是否适合要显示项的数据类型

3.1.1 转换说明

格式:%m.pX%-m.pX

组件 含义 必选 用途 备注
左对齐 左对齐(默认右对齐)
m minimum field width 最小字段宽度 打印字符数<m时会根据对齐方式在前或后放置额外的空格;打印字符数>m时字段宽度会自动扩展为需要的尺寸。
. 分隔 分隔m和p,p存在时才存在
p precision 含义依赖于X的选择 d(数字的最少个数,不够用0补够,默认1);e(小数点后数字个数,默认6) ;f(同e); g(有效数字的最大数量)
X conversion specifier 在显示数值前对其进行那种转换 d(十进制);e(指数);f(浮点数)g(根据数的大小决定指数形式还是浮点数形式)

注意:以上只就部分转换说明符进行了说明。

3.1.2 程序:用printf函数格式化数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* Prints int and float values in various formats
*/


# include <stdio.h>
int main(){
int i;
float x;

i = 40;
x = 839.21;

printf("|%d|%5d|%-5d|%5.3d|\n", i, i, i, i);
printf("|%10.3f|%10.3e|%-10g|\n", x, x, x);

return 0;
}
1
2
3
$ ./tprintf 
|40| 40|40 | 040|
| 839.210| 8.392e+02|839.21 |

3.1.3 转义序列

简介:通过使用\组合其它字符实现对字符的转义,转义字符使字符串包含一些特殊字符而又不会使编译器引发问题,包括非打印的控制字符和对编译器有特殊含义的字符(比如")。

只提供部分

转义字符 含义
\a 警报(响铃)
\b 回退符
\n 换行符
\t 横向制表符
1
printf("Item\tUnit\tPurpose\n\tPrice\tDate\n")

3.2 scanf函数

语法:scanf(格式串, 表达式1, 表达式2, ...)
注意:

  • 编译器不会检查转换说明的数量与输入变量是否相匹配
  • 编译器不会检查转换说明和对应输入变量格式是否合适
  • 忘记在变量前放置符号&将会产生不可预知的结果(比如变量没有初始化)

3.2.1 scanf函数的工作方法

简述:scanf函数本质上是一种“模式匹配”函数,也就是试图把输入的字符组与转换说明匹配成功。
空白字符(white-space):空格、横向(纵向)制表符、换页符、换行符。
匹配规则:

  1. 从左边开始处理输入的字符串的信息
  2. 对格式串中的每一个转换说明,scanf函数努力从输入的数据中定位适当类型的项,并且跳过必要的空白符
  3. 遇到不可能属于当前转换说明的字符时结束对当前转换字符的匹配,并将已经匹配的字符赋值给对应变量
  4. 如果用户输入的字符都和当前转换说明不匹配,则不再查看格式串的剩余部分

3.2.2 格式串中的普通字符

空白字符:当再格式串中遇到一个或多个连续的空白字符时,scanf函数从输入中重复读空白字符直到遇到一个非空白字符。
其他字符:当格式串中国年遇到一个非空白字符时,scanf会把它与下一个输入字符进行比较。如果匹配则丢掉匹配的部分,并针对后面的输入及对应的格式串进行处理;否则异常退出。

3.2.3 混淆printf函数和scanf函数

常见问题

  • 在printf函数调用时在变量前面放置&
  • scanf中格式串中出现不必要的\n,导致交互程序会一直匹配用户输入的空白符

3.2.4 程序:计算持有的股票的价值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* Computes the value of stock holdings
*/


# include <stdio.h>
int main(){
int price, shares;
float num, denom, value;

printf("Enter share price (must inclide a fraction):\n");
scanf("%d%f/%f", &price, &num, &denom);

printf("Enter number of shares:");
scanf("%d", &shares);

value = (price + num / denom) * shares;

printf("Value of holdings:$%.2f\n", value);

}
1
2
3
4
5
$ ./stocks 
Enter share price (must inclide a fraction):
64 18/40
Enter number of shares:100
Value of holdings:$6445.00